home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 November
/
EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso
/
earcd
/
ear
/
uniq.lha
/
uniq.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-11
|
12KB
|
439 lines
/*
* Name: uniq.c
* Author: Oliver Kaufmann
*
* created: ?
* last modified: 10.6.1994
* Version: $VER: uniq 1.1
*
* Doc: uniq.doc
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <dos/dos.h>
#include <functions.h>
#include <string.h>
void CloseAll(char *s);
char *makename(char *s, int blen, int elen, char **tb, char **tex, char *buffer);
char *modifyname(char *tb, int blen, int elen, long sernum, int origlen);
char *savestring(char *s);
struct tbl *feedtbl(char *s, struct tbl *firsttbl, int type);
struct tbl *lookup(char *t, struct tbl *firsttbl, struct tbl *excludetbl);
struct tbl *modifytbl(char *s, char *t, struct tbl *thistbl);
struct tbl *inserttbl(char *s, char *t, int type, struct tbl *firsttbl);
struct tbl *uniq(struct tbl *thistbl, struct tbl *firsttbl,int blen, int elen);
struct tbl *makeuniq(struct tbl *firsttbl, int blen, int elen);
void uniqthislevel(struct tbl *thisdir, char *origpathname, char *newpathname);
void giveout(struct tbl *firsttbl, char *lformat, int allflag, int quoteflag);
struct tbl *freetbl(struct tbl *thistbl);
char ver[] = "$VER: uniq 1.1 (10.6.1994) © by Oliver Kaufmann";
char *usage = "uniq [<options>]\n\
-d[<dir>] : use contents of <dir> as input, otherwise use stdin\n\
-a : print all names, even those which do not change\n\
-f : process files only, no dirs (requires -d option)\n\
-q : enclose output in quotes (rename \"%s\" \"%s\")\n\
-r : recurse sub-dirs (requires -d option)\n\
-l<lformat> : use <lformat> for output (default rename %s %s)\n\
-m[<mformat>] : enable & print <mformat> for dirs (default makedir %s)\n\
-p<pattern> : pattern to apply (default #?)\n\
-b<basenamelength> : max. length of the uniqified string (default 8)\n\
-e<extensionlength> : max. length of the uniqified extension (default 3)";
struct tbl {
char *orig;
char *new;
int type;
struct tbl *nexttbl;
};
struct MyAnchorPath {
struct AChain *ap_Base; /* pointer to first anchor */
struct AChain *ap_Last; /* pointer to last anchor */
LONG ap_BreakBits; /* Bits we want to break on */
LONG ap_FoundBreak; /* Bits we broke on. Also returns ERROR_BREAK */
BYTE ap_Flags; /* New use for extra word. */
BYTE ap_Reserved;
WORD ap_Strlen; /* This is what ap_Length used to be */
struct FileInfoBlock ap_Info;
UBYTE ap_Buf[1]; /* Buffer for path name, allocated by user */
};
#define BUFLEN 256
char pbuf[BUFLEN];
char str1[BUFLEN];
char str2[BUFLEN];
int level = 0;
int quoteflag = 0;
int mformflag = 0;
int allfilendirs = 1;
int allflag = 0;
int recursflag = 0;
int blen=8;
int elen=3;
char *lformat = "rename %s %s";
char *mformat = "makedir %s";
char *pattern="#?";
void main(int argc, char *argv[])
{
struct tbl localtbl;
struct tbl *firsttbl=NULL;
char lbuf[BUFLEN];
char *dirname=NULL;
char *s, *opt;
int i, res;
for(i=1; i<argc; i++) {
if( *(opt=argv[i]) == '-') {
switch(opt[1]) {
case 'd' : dirname = &opt[2]; break;
case 'a' : allflag = 1 ; break;
case 'r' : recursflag = 1 ; break;
case 'q' : quoteflag = 1 ; break;
case 'f' : allfilendirs = 0 ; break;
case 'l' : lformat = &opt[2]; break;
case 'p' : pattern = &opt[2]; break;
case 'm' : mformflag = 1;
if( opt[2] != 0 )
mformat = &opt[2];
break;
case 'b' : if( (blen = atoi(&opt[2]) ) <= 0)
CloseAll("basenamelength must be > 0");
break;
case 'e' : if( (elen = atoi(&opt[2])) < 0)
CloseAll("extensionlength must be >= 0");
break;
default : printf("unknown option: ignored\n");
break;
}
} else if( *opt == '?')
CloseAll(usage);
}
if(dirname != NULL) {
localtbl.orig = dirname;
localtbl.new = "";
localtbl.nexttbl = NULL;
uniqthislevel(&localtbl,dirname,"");
} else {
if( ParsePattern(pattern, pbuf, BUFLEN) == -1)
CloseAll("pattern too long");
while( (res=scanf("%s",lbuf)) != EOF) {
if(res==0)
CloseAll("res = 0");
if(MatchPattern(pbuf, lbuf)) /* nur wenn pattern matched */
firsttbl = feedtbl(lbuf, firsttbl, 0);
}
if(firsttbl != NULL)
if( (firsttbl=makeuniq(firsttbl, blen, elen)) == NULL)
CloseAll("unable to uniqify filetbl");
giveout(firsttbl, lformat, allflag, quoteflag);
}
CloseAll(NULL);
}
#define PATHNAMELEN 256
void uniqthislevel(struct tbl *thisdir, char *origpathname, char *newpathname)
{
struct FileInfoBlock *fib;
struct AnchorPath *ap;
int result, emptyflag = 1;
char origpath[PATHNAMELEN]; /* store full orig path */
char newpath[PATHNAMELEN]; /* store full new path */
struct tbl *looptbl=NULL;
struct tbl *firsttbl=NULL;
BPTR lock, oldlock;
if(thisdir == NULL) {
return;
}
level += 1;
if( (ap=(struct AnchorPath *)malloc(sizeof(struct MyAnchorPath)) ) == NULL)
CloseAll("no memory for MyAnchorPath");
memset(ap,0,sizeof(struct MyAnchorPath)-1); /* crucial ! struct must be 0ed */
/* took me 2 h to find out */
if( (lock=Lock(thisdir->orig,ACCESS_READ)) == 0)
CloseAll("no lock on dir");
oldlock = CurrentDir(lock);
ap->ap_Strlen = 0;
ap->ap_BreakBits = 0;
ap->ap_FoundBreak = 0;
result = MatchFirst(pattern, ap); /* pattern global ! */
if ( result == 0 ) {
do {
emptyflag = 0;
fib = &ap->ap_Info;
firsttbl = feedtbl(fib->fib_FileName, firsttbl, fib->fib_DirEntryType);
} while ( !(result = MatchNext(ap)) );
}
if(result != ERROR_NO_MORE_ENTRIES)
CloseAll("MatchFirst: other error");
MatchEnd(ap);
free(ap);
if(firsttbl != NULL) {
if( (firsttbl=makeuniq(firsttbl, blen, elen)) == NULL)
CloseAll("unable to uniqify filetbl");
}
looptbl = firsttbl;
while (looptbl != NULL) {
strcpy(origpath,origpathname);
if( !AddPart(origpath, looptbl->orig, PATHNAMELEN) )
CloseAll("path to long");
strcpy(newpath, newpathname);
if( !AddPart(newpath, looptbl->new, PATHNAMELEN) )
CloseAll("path to long");
if(mformflag && looptbl->type >= 0) { /* directory special output */
*str1 = 0;
if(quoteflag) strcat(str1,"\"");
strcat(str1,newpath);
if(quoteflag) strcat(str1,"\"");
printf(mformat, str1);
printf("\n");
}
if( allfilendirs || looptbl->type < 0) { /* file output */
if( allflag || strcmp(looptbl->orig, looptbl->new) ) {
*str1 = 0;
if(quoteflag) strcat(str1,"\"");
strcat(str1,origpath);
if(quoteflag) strcat(str1,"\"");
*str2 = 0;
if(quoteflag) strcat(str2,"\"");
strcat(str2,newpath);
if(quoteflag) strcat(str2,"\"");
printf(lformat ,str1, str2);
printf("\n");
}
}
if(recursflag && looptbl->type >= 0) {
uniqthislevel(looptbl, origpath, newpath);
}
looptbl = looptbl->nexttbl;
}
CurrentDir(oldlock);
UnLock(lock);
freetbl(firsttbl); /* free memory */
level -= 1;
}
struct tbl *makeuniq(struct tbl *firsttbl, int blen, int elen)
{
struct tbl *thistbl;
thistbl = firsttbl;
while(thistbl != NULL) {
if( uniq(thistbl, firsttbl, blen, elen) == NULL)
return NULL;
thistbl = thistbl->nexttbl;
}
return firsttbl;
}
struct tbl *uniq(struct tbl *thistbl, struct tbl *firsttbl,int blen, int elen)
{
char lbuf[BUFLEN];
char buffer[BUFLEN];
char *t, *tb, *tex;
char *s;
long sernum;
int origlen;
s = thistbl->orig;
makename(s, blen, elen, &tb, &tex, buffer); /* name und extension */
origlen = strlen(tb); /* base name length */
for(sernum = 0; ; sernum++) {
strcpy(lbuf,tb);
strcat(lbuf,tex);
if( lookup(lbuf, firsttbl, thistbl) == NULL )
break;
if( modifyname(tb, blen, elen, sernum, origlen) == 0)
return NULL;
}
t = savestring(lbuf);
modifytbl(s, t, thistbl);
return thistbl;
}
struct tbl *inserttbl(char *s, char *t, int type, struct tbl *firsttbl)
{
struct tbl *thistbl;
if( (thistbl=malloc(sizeof(struct tbl))) == NULL)
CloseAll("no memory for tbl");
thistbl->type = type;
thistbl->orig = s;
thistbl->new = t;
thistbl->nexttbl = firsttbl;
return thistbl;
}
struct tbl *modifytbl(char *s, char *t, struct tbl *thistbl)
{
thistbl->orig = s;
thistbl->new = t;
return thistbl;
}
struct tbl *feedtbl(char *s, struct tbl *firsttbl, int type)
{
char *m;
m = savestring(s);
return inserttbl(m, m, type, firsttbl);
}
char *savestring(char *s)
{
char *mem;
if( (mem=malloc(strlen(s)+1)) == NULL)
CloseAll("no memory for string");
strcpy(mem, s);
return mem;
}
struct tbl *lookup(char *t, struct tbl *firsttbl, struct tbl *excludetbl)
{
while(firsttbl != NULL) {
if( (strcmp(t, firsttbl->new) == 0) && (firsttbl != excludetbl) )
break;
firsttbl = firsttbl->nexttbl;
}
return firsttbl;
}
char *modifyname(char *tb, int blen, int elen, long sernum, int origlen)
{
char lbuf[BUFLEN];
int sl, i, j, pos;
sprintf(lbuf,"%x",sernum);
if( (sl = strlen(lbuf)) > blen ) /* sernum zu groß */
return NULL;
pos = origlen;
if( origlen + sl > blen )
pos = blen-sl;
strncpy(tb+pos, lbuf, sl);
return tb;
}
char *makename(char *s, int blen, int elen, char **tb, char **tex, char *buffer)
{
char *t;
int n,m;
int sl,i;
*tb = buffer;
for(n=0, t=s ; (*t != '\0') && (*t != '.') ; *t++, n++);
strncpy(buffer, s, n); /* es wird evtl mehr kopiert */
while(n<blen)
buffer[n++] = '\0'; /* auffüllen */
buffer[blen] = '\0'; /* rest abschneiden */
n = blen+1; /* ab hier extension */
buffer[n] = '\0'; /* default ist leer */
*tex = &buffer[n];
if(elen != 0 ) {
for(i = sl = strlen(s)-1; sl >= 0; sl--)
if(s[sl] == '.')
break;
if(s[sl] == '.') {
buffer[n++] = '.';
strncpy(&buffer[n], &s[sl+1], i-sl+1); /* 0 mitkopieren */
n += i-sl;
}
buffer[n] = '\0'; /* default ist leer */
buffer[blen+elen+1+1]='\0';
}
return *tb;
}
void giveout(struct tbl *firsttbl, char *lformat, int allflag, int quoteflag)
{
while (firsttbl != NULL) {
if( allflag || strcmp(firsttbl->orig, firsttbl->new) ) {
*str1 = 0;
if(quoteflag) strcat(str1,"\"");
strcat(str1,firsttbl->orig);
if(quoteflag) strcat(str1,"\"");
*str2 = 0;
if(quoteflag) strcat(str2,"\"");
strcat(str2,firsttbl->new);
if(quoteflag) strcat(str2,"\"");
printf(lformat, str1, str2);
printf("\n");
}
firsttbl = firsttbl->nexttbl;
}
}
struct tbl *freetbl(struct tbl *thistbl)
{
struct tbl *tmptbl;
while(thistbl != NULL) {
if(thistbl->orig != NULL)
free(thistbl->orig);
if( (thistbl->new != NULL) && (thistbl->new != thistbl->orig) )
free(thistbl->new);
tmptbl = thistbl;
thistbl = thistbl->nexttbl;
free(tmptbl);
}
return NULL;
}
void CloseAll(char *s)
{
if(s != NULL)
printf("%s\n",s);
exit(0);
}